#ifndef __CONNECTION_PROXY_included
#define __CONNECTION_PROXY_included

#include <boost/lexical_cast.hpp>
#include <boost/weak_ptr.hpp>
#include "Connection.h"
#include "ConnectionControl.h"
#include "ClientRequest.h"
#include "../engine/ServerDescriptor.h"
#include "ChannelTCP.h"

using namespace Engine;

class CConnectionProxy : public CConnection {

	boost::weak_ptr<CConnectionControl> mParent;
	string mPeer;
	string mChannel;

public :

	CConnectionProxy(CServerDescriptor& sd, boost::shared_ptr<CConnectionControl> control_conn, bool bind_parent) :
		CConnection(sd.mIp, sd.mPort, boost::shared_ptr<CChannel>(new CChannelTCP(sd.mIp, sd.mPort)), control_conn->GetPeerConfig()),
		mPeer(sd.GetParameter(string("peer"))), 
		mChannel(sd.GetParameter(string("channel")))
	{
		if(bind_parent) mParent = control_conn;
	}

	virtual ~CConnectionProxy() {
		Close();
	}

	virtual boost::shared_ptr<CResponse> SendRequest(boost::shared_ptr<CRequest> r) {
		return CConnection::SendRequest(r, 1);
	}

	virtual void Setup() {

		boost::shared_ptr<CRequest> r(new CClientRequest(string(COMMAND_SETUP)));

		DebugStream << "CConnectionProxy - channel(" << mChannel << ") peer(" << mPeer << ")\n";
		if(mPeer.length() > 0) r->AddParameter(string("peer"), mPeer);
		if(mChannel.length() > 0) r->AddParameter(string("channel"), mChannel);
		
		boost::shared_ptr<CResponse> resp = SendRequest(r);
		if(!resp || resp->GetStatus() != RESPONSE_STATUS_OK) {
			Close();
			throw std::exception("Setup proxy connection failed");
		}

		boost::shared_ptr<CConnectionControl> control_conn = mParent.lock();
		if(control_conn) {
			control_conn->AddDataConnection(
				boost::dynamic_pointer_cast<CConnection, IPackageReceiver>(shared_from_this())
				);
		}
	}

	
	virtual void Close() {
		
		boost::shared_ptr<CConnectionControl> control_conn = mParent.lock();
		if(control_conn) 
			control_conn->RemoveDataConnection(
				boost::dynamic_pointer_cast<CConnection, IPackageReceiver>(shared_from_this())
				);
		
		CConnection::Close();
	}
};

#endif //__CONNECTION_PROXY_included